package com.gtenacg.cartoonservice.service.impl;

import com.gtenacg.cartoonservice.common.Const;
import com.gtenacg.cartoonservice.compent.MyRestTemplate;
import com.gtenacg.cartoonservice.compent.WindowsExplorerStringComparator;
import com.gtenacg.cartoonservice.mapper.NovelMapper;
import com.gtenacg.cartoonservice.pojo.model.*;
import com.gtenacg.cartoonservice.pojo.vo.NovelVo;
import com.gtenacg.cartoonservice.service.NovelService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author 86198
* @description 针对表【gt_novel(小说表)】的数据库操作Service实现
* @createDate 2024-05-22 08:46:33
*/
@Service
@RequiredArgsConstructor
public class NovelServiceImpl implements NovelService{
    private final NovelMapper novelMapper;

    @Override
    public List<Novel> list() {
        return novelMapper.list();
    }

    @Override
    public List<Novel> search(String name) {
        return novelMapper.search(name);
    }

    @Override
    public List<Novel> random(Integer num) {
        return novelMapper.random(num);
    }

    @Override
    public List<Novel> getByNids(List<Integer> nids) {
        return novelMapper.getByNids(nids);
    }



    @Override
    public List<String> getChapterList(Novel novel) {
        List<String> list = MyRestTemplate.FileServiceGetChapter(novel.getSrc(), true);
        list.sort(new WindowsExplorerStringComparator());
        return list;
    }

    @Override
    public void update(Novel novel) {
        novelMapper.update(novel);
    }

    @Override
    public Integer insert(Novel novel) {
        novel.setSrc(Const.FILE_PATH + Const.NOVEL_PATH + novel.getName() + "/");
        novel.setCover("");
        novelMapper.insert(novel);
        return novel.getNid();
    }

    @Override
    public void delete(List<Integer> nids) {
        novelMapper.delete(nids);
    }


    @Override
    public List<NovelVo> assembleNovelVo(List<Novel> novels,
                                         List<NovelType> types, List<RelationNovelType> relationTypes,
                                         List<Author> authors, List<RelationNovelAuthor> relationAuthors) {

        Map<Integer, NovelType> typeMap = types.stream()
                .collect(Collectors.toMap(NovelType::getNtid, Function.identity()));

        Map<Integer, List<Integer>> relationTypesMap = relationTypes.stream()
                .collect(Collectors.groupingBy(
                        RelationNovelType::getNid,
                        Collectors.mapping(RelationNovelType::getNtid, Collectors.toList())
                ));

        Map<Integer, Author> authorMap = authors.stream()
                .collect(Collectors.toMap(Author::getAid, Function.identity()));

        Map<Integer, List<Integer>> relationAuthorsMap = relationAuthors.stream()
                .collect(Collectors.groupingBy(
                        RelationNovelAuthor::getNid,
                        Collectors.mapping(RelationNovelAuthor::getAid, Collectors.toList())
                ));


        // 数据拼装 List<CartoonVo> List
        List<NovelVo> list = novels.stream()
                // 通过cid,获取对应的cartoonVO对象
                .map(novel -> {
                    Integer nid = novel.getNid();

                    //通过cid,获取对应typeName列表
                    List<Integer> ntidList = relationTypesMap.getOrDefault(nid, Collections.emptyList());
                    List<String> typeNames = ntidList.stream()
                            .map(ntid -> typeMap.getOrDefault(ntid, new NovelType()).getName()).toList();

                    //通过cid,获取对应authorName列表
                    List<Integer> aidList = relationAuthorsMap.getOrDefault(nid, Collections.emptyList());
                    List<String> authorNames = aidList.stream()
                            .map(aid -> authorMap.getOrDefault(aid, new Author()).getName()).toList();

                    return new NovelVo(novel, typeNames, authorNames);
                })
                .toList();


        return list;
    }
}




